package org.libermundi.theorcs.chronicles.model;

import java.util.SortedSet;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.Sort;
import org.hibernate.annotations.SortType;
import org.hibernate.search.annotations.Analyzer;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.Store;
import org.libermundi.theorcs.chronicles.ChronicleConstants;
import org.libermundi.theorcs.core.model.Searchable;
import org.libermundi.theorcs.security.model.User;
import org.libermundi.theorcs.security.model.UserStatefulEntity;

import com.google.common.collect.Sets;

@Entity(name="Chronicle")
@Table(name=ChronicleConstants.TBL_CHRONICLE)
@Indexed(index="Chronicles")
@Analyzer(definition = "SuggestionAnalyzer")
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
public final class Chronicle extends UserStatefulEntity implements Searchable{
	public final static String PROP_TITLE="title";
	public final static String PROP_SUBTITLE="subTitle";
	public final static String PROP_DESCRIPTION="description";
	public final static String PROP_FACTIONS="factions";
	
	private static final String[] SEARCHABLE_FIELDS = new String[]{PROP_TITLE, PROP_SUBTITLE, PROP_DESCRIPTION};
	
	private static final long serialVersionUID = -623462418684825618L;
	
	private String _title;
	private String _subTitle;
	private String _description;
	private Game _game;
	private User _admin;
	private SortedSet<Faction> _factions = Sets.newTreeSet();

	@Basic
	@Column(name=Chronicle.PROP_TITLE, length=50)
	@Field(store=Store.YES,index=Index.YES)
	public String getTitle() {
		return _title;
	}

	@Basic
	@Column(name=Chronicle.PROP_SUBTITLE, length=50)	
	@Field(store=Store.YES,index=Index.YES)
	public String getSubTitle() {
		return _subTitle;
	}
	
	@Lob
	@Column(name=Chronicle.PROP_DESCRIPTION,nullable=true)
	@Field(store=Store.YES,index=Index.YES)
	public String getDescription() {
		return _description;
	}

	@ManyToOne(cascade = CascadeType.ALL,fetch=FetchType.LAZY)
	@JoinColumn(name="gameId")
	public Game getGame() {
		return _game;
	}

	@ManyToOne(cascade = CascadeType.ALL,fetch=FetchType.LAZY)
	@JoinColumn(name="adminId")
	public User getAdmin() {
		return _admin;
	}
	
	@OneToMany(cascade=CascadeType.ALL,fetch=FetchType.LAZY,orphanRemoval=true,mappedBy=Faction.PROP_CHRONICLE)
	@Sort(type=SortType.NATURAL)
	public SortedSet<Faction> getFactions() {
		return _factions;
	}

	public void setTitle(String title) {
		_title = title;
	}

	public void setSubTitle(String subTitle) {
		_subTitle = subTitle;
	}

	public void setDescription(String description) {
		_description = description;
	}

	public void setGame(Game game) {
		_game = game;
	}

	public void setAdmin(User admin) {
		_admin = admin;
	}
	
	public void setFactions(SortedSet<Faction> factions){
		_factions = factions;
	}

	@Override
	public String toString() {
		return "Chronicle [Title=" + _title + ", Game=" + _game + ", Admin=" + _admin + "]";
	}
	
	/* (non-Javadoc)
	 * @see org.libermundi.theorcs.core.model.Searchable#loadSearchfields()
	 */
	@Override
	public String[] loadSearchfields() {
		return SEARCHABLE_FIELDS;
	}
}
